from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework import generics
from rest_framework.views import APIView
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema

from user_app.models import User
from user_app.serializers import UserSerializer, UserDetailSerializer
from .utils import *
# Create your views here.
class LoginView(APIView):
    @swagger_auto_schema(
        operation_summary="用户登录接口",
        operation_description="用户通过手机号和密码进行登录，成功后返回访问token和刷新token",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            required=['phone', 'password'],
            properties={
                'phone': openapi.Schema(type=openapi.TYPE_STRING, description='用户手机号'),
                'password': openapi.Schema(type=openapi.TYPE_STRING, description='用户密码'),
            }
        ),
        responses={
            200: openapi.Response(
                description='登录成功',
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'code': openapi.Schema(type=openapi.TYPE_INTEGER, description='状态码，0表示成功'),
                        'message': openapi.Schema(type=openapi.TYPE_STRING, description='成功消息'),
                        'access_token': openapi.Schema(type=openapi.TYPE_STRING, description='访问token'),
                        'refresh_token': openapi.Schema(type=openapi.TYPE_STRING, description='刷新token'),
                    }
                )
            ),
            404: openapi.Response(description='用户不存在'),
            401: openapi.Response(description='密码错误')
        }
    )
    def post(self, request):
        """
        用户登录接口
        """
        phone = request.data.get('phone')
        password = request.data.get('password')
        try:
            user = User.objects.get(phone=phone)

        except User.DoesNotExist:
            return Response({'message': '用户不存在'}, status=status.HTTP_404_NOT_FOUND)
        
        if not user.check_password(password):
            return Response({'message': '密码错误'}, status=status.HTTP_401_UNAUTHORIZED)
        
        # 生成访问token和刷新token
        access_token = generate_access_token(user.id)
        refresh_token = generate_refresh_token(user.id)
        
        return Response({
            'code': 0,
            'message': '登录成功', 
            'access_token': access_token,
            'refresh_token': refresh_token
            }, status=status.HTTP_200_OK)

class RegisterView(APIView):
    @swagger_auto_schema(
        operation_summary="用户注册接口",
        operation_description="用户通过手机号和密码进行注册，创建新用户",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            required=['phone', 'password'],
            properties={
                'phone': openapi.Schema(type=openapi.TYPE_STRING, description='用户手机号'),
                'password': openapi.Schema(type=openapi.TYPE_STRING, description='用户密码'),
                'nickname': openapi.Schema(type=openapi.TYPE_STRING, description='用户昵称'),
                'avatar': openapi.Schema(type=openapi.TYPE_STRING, description='用户头像URL'),
                'gender': openapi.Schema(type=openapi.TYPE_INTEGER, description='用户性别，0：男，1：女'),
            }
        ),
        responses={
            200: openapi.Response(
                description='注册成功',
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'code': openapi.Schema(type=openapi.TYPE_INTEGER, description='状态码，0表示成功'),
                        'message': openapi.Schema(type=openapi.TYPE_STRING, description='成功消息'),
                    }
                )
            ),
            400: openapi.Response(description='注册失败，参数错误')
        }
    )
    def post(self, request):
        """
        用户注册接口
        """
        serializer = UserSerializer(data=request.data)

        if serializer.is_valid():
            serializer.save()
            return Response({'message': '注册成功', 'code':0}, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class ProfileView(APIView):
    """
    用户信息接口
    """
    @swagger_auto_schema(
        operation_summary="获取用户信息接口",
        operation_description="获取当前登录用户的详细信息，需要携带token认证",
        manual_parameters=[
            openapi.Parameter(
                'Authorization', openapi.IN_HEADER, 
                description="认证token，格式：Bearer {token}",
                type=openapi.TYPE_STRING
            )
        ],
        responses={
            200: openapi.Response(
                description='获取用户信息成功',
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'id': openapi.Schema(type=openapi.TYPE_INTEGER, description='用户ID'),
                        'phone': openapi.Schema(type=openapi.TYPE_STRING, description='用户手机号'),
                        'nickname': openapi.Schema(type=openapi.TYPE_STRING, description='用户昵称'),
                        'avatar': openapi.Schema(type=openapi.TYPE_STRING, description='用户头像URL'),
                        'gender': openapi.Schema(type=openapi.TYPE_INTEGER, description='用户性别'),
                        'job_title': openapi.Schema(type=openapi.TYPE_STRING, description='职位'),
                        'introduction': openapi.Schema(type=openapi.TYPE_STRING, description='个人简介'),
                        'create_at': openapi.Schema(type=openapi.TYPE_STRING, format='date-time', description='创建时间'),
                    }
                )
            ),
            401: openapi.Response(description='未授权，请提供有效的token')
        }
    )
    def get(self, request):
        """
        获取用户信息接口
        """
        token = request.META.get("HTTP_AUTHORIZATION")
        if not token:
            return Response({'message': '未授权，请提供有效的token'}, status=status.HTTP_401_UNAUTHORIZED)
            
        data = verify_token(token)
        if not data:
            return Response({'message': '无效的token'}, status=status.HTTP_401_UNAUTHORIZED)
        
        user = User.objects.filter(id=data.get("id")).first()
        if not user:
            return Response({'message': '用户不存在'}, status=status.HTTP_404_NOT_FOUND)
            
        serializer = UserDetailSerializer(user)
        return Response(serializer.data, status=status.HTTP_200_OK)

# user_app/views.py 添加token刷新视图
class TokenRefreshView(APIView):
    @swagger_auto_schema(
        operation_summary="刷新token接口",
        operation_description="使用刷新token获取新的访问token",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            required=['refresh_token'],
            properties={'refresh_token': openapi.Schema(type=openapi.TYPE_STRING, description='刷新token')}
        ),
        responses={
            200: openapi.Response(
                description='刷新成功',
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'code': openapi.Schema(type=openapi.TYPE_INTEGER, description='状态码，0表示成功'),
                        'message': openapi.Schema(type=openapi.TYPE_STRING, description='成功消息'),
                        'access_token': openapi.Schema(type=openapi.TYPE_STRING, description='新的访问token'),
                    }
                )
            ),
            401: openapi.Response(description='无效的刷新token')
        }
    )
    def post(self, request):
        refresh_token = request.data.get('refresh_token')
        if not refresh_token:
            return Response({'code': 1, 'message': '请提供刷新token'}, status=status.HTTP_400_BAD_REQUEST)
        
        # 验证刷新token
        payload = verify_token(refresh_token, token_type='refresh')
        if not payload:
            return Response({'code': 1, 'message': '无效的刷新token'}, status=status.HTTP_401_UNAUTHORIZED)
        
        user_id = payload.get('id')
        # 生成新的访问token
        new_access_token = generate_access_token(user_id)
        
        return Response({'code': 0, 'message': '刷新成功', 'access_token': new_access_token}, status=status.HTTP_200_OK)

# 添加修改用户信息接口
class UpdateUserInfoView(APIView):
    @swagger_auto_schema(
        operation_summary="修改用户信息接口",
        operation_description="修改当前登录用户的基本信息，需要携带token认证",
        manual_parameters=[
            openapi.Parameter(
                'Authorization', openapi.IN_HEADER, 
                description="{token}",
                type=openapi.TYPE_STRING
            )
        ],
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            properties={
                'nickname': openapi.Schema(type=openapi.TYPE_STRING, description='用户昵称'),
                'gender': openapi.Schema(type=openapi.TYPE_INTEGER, description='用户性别，0：男，1：女'),
                'job_title': openapi.Schema(type=openapi.TYPE_STRING, description='职位'),
                'introduction': openapi.Schema(type=openapi.TYPE_STRING, description='个人简介'),
                'avatar': openapi.Schema(type=openapi.TYPE_STRING, description='用户头像URL'),
            }
        ),
        responses={
            200: openapi.Response(
                description='修改成功',
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'code': openapi.Schema(type=openapi.TYPE_INTEGER, description='状态码，0表示成功'),
                        'message': openapi.Schema(type=openapi.TYPE_STRING, description='成功消息'),
                    }
                )
            ),
            401: openapi.Response(description='未授权，请提供有效的token')
        }
    )
    def put(self, request):
        """
        修改用户信息接口
        """
        token = request.META.get("HTTP_AUTHORIZATION")
        if not token:
            return Response({'code': 1, 'message': '未授权，请提供有效的token'}, status=status.HTTP_401_UNAUTHORIZED)
            
        data = verify_token(token)
        if not data:
            return Response({'code': 1, 'message': '无效的token'}, status=status.HTTP_401_UNAUTHORIZED)
        
        user = User.objects.filter(id=data.get("id")).first()
        if not user:
            return Response({'code': 1, 'message': '用户不存在'}, status=status.HTTP_404_NOT_FOUND)
            
        # 更新用户信息
        update_data = request.data
        
        if 'nickname' in update_data:
            user.nickname = update_data['nickname']
        if 'gender' in update_data:
            user.gender = update_data['gender']
        if 'job_title' in update_data:
            user.job_title = update_data['job_title']
        if 'introduction' in update_data:
            user.introduction = update_data['introduction']
        if 'avatar' in update_data:
            user.avatar = update_data['avatar']
            
        user.save()
        
        return Response({'code': 0, 'message': '修改成功'}, status=status.HTTP_200_OK)

# 添加修改密码接口
class ChangePasswordView(APIView):
    @swagger_auto_schema(
        operation_summary="修改密码接口",
        operation_description="修改当前登录用户的密码，需要携带token认证",
        manual_parameters=[
            openapi.Parameter(
                'Authorization', openapi.IN_HEADER, 
                description="{token}",
                type=openapi.TYPE_STRING
            )
        ],
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            required=['old_password', 'new_password'],
            properties={
                'old_password': openapi.Schema(type=openapi.TYPE_STRING, description='旧密码'),
                'new_password': openapi.Schema(type=openapi.TYPE_STRING, description='新密码'),
            }
        ),
        responses={
            200: openapi.Response(
                description='修改成功',
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'code': openapi.Schema(type=openapi.TYPE_INTEGER, description='状态码，0表示成功'),
                        'message': openapi.Schema(type=openapi.TYPE_STRING, description='成功消息'),
                    }
                )
            ),
            401: openapi.Response(description='未授权，请提供有效的token'),
            400: openapi.Response(description='密码错误或参数无效')
        }
    )
    def put(self, request):
        """
        修改密码接口
        """
        token = request.META.get("HTTP_AUTHORIZATION")
        if not token:
            return Response({'code': 1, 'message': '未授权，请提供有效的token'}, status=status.HTTP_401_UNAUTHORIZED)
            
        data = verify_token(token)
        if not data:
            return Response({'code': 1, 'message': '无效的token'}, status=status.HTTP_401_UNAUTHORIZED)
        
        user = User.objects.filter(id=data.get("id")).first()
        if not user:
            return Response({'code': 1, 'message': '用户不存在'}, status=status.HTTP_404_NOT_FOUND)
            
        old_password = request.data.get('old_password')
        new_password = request.data.get('new_password')
        
        if not old_password or not new_password:
            return Response({'code': 1, 'message': '请提供旧密码和新密码'}, status=status.HTTP_400_BAD_REQUEST)
            
        # 验证旧密码
        if not user.check_password(old_password):
            return Response({'code': 1, 'message': '旧密码错误'}, status=status.HTTP_400_BAD_REQUEST)
            
        # 修改密码
        user.password = new_password
        user.save()
        
        return Response({'code': 0, 'message': '密码修改成功'}, status=status.HTTP_200_OK)

# 添加忘记密码/重置密码接口
class ResetPasswordView(APIView):
    @swagger_auto_schema(
        operation_summary="重置密码接口",
        operation_description="用户通过手机号重置密码",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            required=['phone', 'new_password'],
            properties={
                'phone': openapi.Schema(type=openapi.TYPE_STRING, description='用户手机号'),
                'new_password': openapi.Schema(type=openapi.TYPE_STRING, description='新密码'),
            }
        ),
        responses={
            200: openapi.Response(
                description='重置成功',
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'code': openapi.Schema(type=openapi.TYPE_INTEGER, description='状态码，0表示成功'),
                        'message': openapi.Schema(type=openapi.TYPE_STRING, description='成功消息'),
                    }
                )
            ),
            404: openapi.Response(description='用户不存在')
        }
    )
    def post(self, request):
        """
        重置密码接口
        """
        phone = request.data.get('phone')
        new_password = request.data.get('new_password')
        
        if not phone or not new_password:
            return Response({'code': 1, 'message': '请提供手机号和新密码'}, status=status.HTTP_400_BAD_REQUEST)
            
        try:
            user = User.objects.get(phone=phone)
        except User.DoesNotExist:
            return Response({'code': 1, 'message': '用户不存在'}, status=status.HTTP_404_NOT_FOUND)
            
        # 重置密码
        user.password = new_password
        user.save()
        
        return Response({'code': 0, 'message': '密码重置成功'}, status=status.HTTP_200_OK)

# 添加登出接口
class LogoutView(APIView):
    @swagger_auto_schema(
        operation_summary="用户登出接口",
        operation_description="用户登出，需要携带token认证",
        manual_parameters=[
            openapi.Parameter(
                'Authorization', openapi.IN_HEADER, 
                description="认证token，格式：Bearer {token}",
                type=openapi.TYPE_STRING
            )
        ],
        responses={
            200: openapi.Response(
                description='登出成功',
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'code': openapi.Schema(type=openapi.TYPE_INTEGER, description='状态码，0表示成功'),
                        'message': openapi.Schema(type=openapi.TYPE_STRING, description='成功消息'),
                    }
                )
            ),
            401: openapi.Response(description='未授权，请提供有效的token')
        }
    )
    def post(self, request):
        """
        用户登出接口
        """
        # 在当前实现中，JWT是无状态的，登出只需要前端删除token即可
        # 这里可以添加额外的逻辑，如将token加入黑名单等
        token = request.META.get("HTTP_AUTHORIZATION")
        if not token:
            return Response({'code': 1, 'message': '未授权，请提供有效的token'}, status=status.HTTP_401_UNAUTHORIZED)
            
        data = verify_token(token)
        if not data:
            return Response({'code': 1, 'message': '无效的token'}, status=status.HTTP_401_UNAUTHORIZED)
            
        # 这里可以实现token黑名单逻辑
        # 例如：将token存入数据库的黑名单表中
            
        return Response({'code': 0, 'message': '登出成功'}, status=status.HTTP_200_OK)
